/*
 * Array ES5 extend
 */
Array.isArray = function (vArg) {
	return Object.prototype.toString.call(vArg) === "[object Array]";
}

Array.prototype.forEach = function (fn, context) {
    for (var i = 0; i < this.length; i++) {
        if (typeof fn === "function" && Object.prototype.hasOwnProperty.call(this, i)) {
            fn.call(context, this[i], i, this);
        }
    }
}

Array.prototype.map = function (fn, context) {
    var arr = [];
    if (typeof fn === "function") {
        for (var k = 0, length = this.length; k < length; k++) {
            arr.push(fn.call(context, this[k], k, this));
        }
    }
    return arr;
}

Array.prototype.every = function (fn, context) {
    var passed = true;
    if (typeof fn === "function") {
        for (var k = 0, length = this.length; k < length; k++) {
            if (passed === false) break;
            passed = !!fn.call(context, this[k], k, this);
        }
    }
    return passed;
}

Array.prototype.filter = function (fn, context) {
    var arr = [];
    if (typeof fn === "function") {
        for (var k = 0, length = this.length; k < length; k++) {
            fn.call(context, this[k], k, this) && arr.push(this[k]);
        }
    }
    return arr;
}

Array.prototype.some = function (fn, context) {
    var passed = false;
    if (typeof fn === "function") {
        for (var k = 0, length = this.length; k < length; k++) {
            if (passed === true) break;
            passed = !!fn.call(context, this[k], k, this);
        }
    }
    return passed;
}

Array.prototype.indexOf = function (item, index) {
    var n = this.length,
        i = index == null ? 0 : index < 0 ? Math.max(0, n + index) : index;
    for (; i < n; i++) {
        if (i in this && this[i] === item) {
            return i
        }
    }
    return -1
}

Array.prototype.lastIndexOf = function (item, index) {
    var n = this.length,
        i = index == null ? n-1 : index < 0 ? Math.max(0, n + index) : index;
    for (; i >= 0; i--) {
        if (i in this && this[i] === item) {
            return i;
        }
    }
    return -1;
}

//reduce 遍历数组调用指定函数(函数需要2个参数)，每次把调用函数的返回值与下一个元素当做函数参数继续调用。
//对数组进行求和等操作很实用
Array.prototype.reduce = function (fun,initval) {
	var length=this.length;
	if(length==0) return "";
	if(length==1){
		return initval?fun(initval,this[0]):this[0];
	}
	var val=initval,
		firstindex=initval?0:2;
	if(!initval){
		val=fun(this[0],this[1]);
	}
	for(var i=firstindex;i<length;i++){
		val=fun(val,this[i]);
	}
	return val;
}

//reduceRight 与reduce一样 只是从右到左遍历数组
Array.prototype.reduceRight = function (fun,initval) {
	var length=this.length;
	if(length==0) return "";
	if(length==1){
		return initval?fun(initval,this[0]):this[0];
	}
	var val=initval,
		firstindex=initval?length-1:length-3;
	if(!initval){
		val=fun(this[length-1],this[length-2]);
	}
	for(var i=firstindex;i>=0;i--){
		val=fun(val,this[i]);
	}
	return val;
}